const Koa = require('koa')
const app = new Koa()
const views = require('koa-views') // 使用koa渲染页面的中间件，配合视图模板引擎.pug或者ejs来实现
const json = require('koa-json') // 参数转json对象
const onerror = require('koa-onerror') // 错误监听
const bodyparser = require('koa-bodyparser') // 获取get/post发送的数据,做转换用
const jwt = require('jsonwebtoken')
const koajwt = require('koa-jwt')
// const logger = require('koa-logger')
const log4js = require('./utils/log4j3')
const util = require('./utils/util')
const users = require('./routes/users')
const router = require('koa-router')()
    // const log = log4js.getLogger()

// error handler
onerror(app)

// 加载数据库配置并连接
require('./config/db')

// middlewares
app.use(bodyparser({ 
    enableTypes: ['json', 'form', 'text'] // 接收数据格式json,form,text
}))
app.use(json())
    // app.use(logger())

// 设置静态资源允许访问的目录，不然在访问.pug文件的时候，public下的一些css,js文件是访问不到的
// 但是现在一般都是使用的前后端分离的开发模式，页面页不会用.pug来写，所以一般这样的设置没多大作用,public和views文件夹用不上
app.use(require('koa-static')(__dirname + '/public')) 
app.use(views(__dirname + '/views', {
    extension: 'pug'
}))

// 当以下代码报错时输出到error级别对应的日志中去，
// 那么app.use(async(ctx, next) => { log4js.info()})这段代码将不被执行，即代码被阻塞
// app.use(() => {
//     ctx.body = 'ERROR logger BODY'
// })

// logger
app.use(async(ctx, next) => {
    log4js.info(`get params: ${JSON.stringify(ctx.request.query)}`)
    log4js.info(`post params:${JSON.stringify(ctx.request.body)}`)
    // const start = new Date()
    await next().catch((err) => {
        if(err.status == 401){
            ctx.status = 200
            ctx.body = util.fail('Token认证失败', util.CODE.AUTH_ERROR)
        } else {
            throw err;
        }
    })
        // log4js.level = "error"
        // log4js.error("New error msgs")
    
        // log.debug("Some debug2 messages")
        // log.info('Some info messages')
        // const ms = new Date() - start
        // console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

// 对jwt加密的数据是否过期和篡改的拦截,校验失败后koajwt底层会把请求码改成401
app.use(koajwt({secret: 'imooc'}).unless({
    path: [/^\/api\/user\/login/]
}))
// routes
router.prefix('/api')
// router.get('/leave/count', ctx => {
//     // const token = ctx.request.headers.authorization.split(' ')[1]
//     // const payload = jwt.verify(token, 'imooc')
//     ctx.body = 'payload'
// })

router.use(users.routes(), users.allowedMethods()) // 加载局部(二级)路由
app.use(router.routes(), router.allowedMethods()) // 加载全局路由

// error-handling
app.on('error', (err, ctx) => {
    // console.error('server error', err, ctx)
    log4js.error(`${err.stack}`)
});

module.exports = app